<template>
  <div>
    <el-card>
      <template #header>
        <div class="card-header">
          <span class="title">知识分类</span>
          <el-button class="button" :icon="Download" @click="exportData"
            >导出</el-button
          >
        </div>
      </template>
      <el-tree
        node-key="id"
        :props="treeProps"
        :load="loadNode"
        lazy
        ref="treeRef"
        :expand-on-click-node="false"
      >
        <template #default="{ node, data }">
          <div class="custom-tree-node">
            <span class="label-name" :title="node.label">{{ node.label }}</span>
            <div class="btn-div">
              <el-link
                @click="appendSub(data)"
                :disabled="node.level == 1"
                :type="node.level == 1 ? 'info' : 'primary'"
                >添加同级</el-link
              >
              <el-link
                :type="node.level >= 9 ? 'info' : 'primary'"
                @click="appendSon(data)"
                :disabled="node.level >= 9"
                >添加子级</el-link
              >
              <el-link type="primary" @click="renameDia(data)">重命名</el-link>
              <el-link
                @click="removeDia(data)"
                :disabled="node.level == 1"
                :type="node.level == 1 ? 'info' : 'primary'"
                >删除</el-link
              >
            </div>
          </div>
        </template>
      </el-tree>
    </el-card>

    <el-dialog
      v-model="dialogVisible"
      :title="diaTitle"
      width="30%"
      :before-close="handleClose"
    >
      <avue-form
        :option="option"
        v-model="formData"
        @submit="handleSubmit"
        ref="formRef"
      ></avue-form>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import type Node from "element-plus/es/components/tree/src/model/node";
import { ElMessageBox, ElMessage } from "element-plus";
import { Download } from "@element-plus/icons-vue";
import {
  getTree,
  addSub,
  addSon,
  remove,
  rename,
  download,
  removeValidate,
} from "@/api/buildKg/classified";

interface Tree {
  id: number;
  name: string;
  parentId?: string | number;
  children?: Tree[];
  isLeaf?: boolean;
}
const formRef = ref();
const treeRef = ref({});
const treeProps = reactive({
  label: "name",
  // children: "itemList",
  isLeaf: "isLeaf",
});
const formData = ref({});

let diaTitle = ref("添加同级");
let clickNodeData: Ref<any> = ref({}); // 操作的node节点数据
const appendSub = (data: Tree) => {
  diaTitle.value = "添加同级";
  clickNodeData.value = data;
  dialogVisible.value = true;
  // console.log(data, "data");
};
const appendSon = (data: Tree) => {
  diaTitle.value = "添加子级";
  clickNodeData.value = data;
  dialogVisible.value = true;
};
const renameDia = (data: Tree) => {
  diaTitle.value = "重命名";
  clickNodeData.value = data;
  formData.value = data;
  dialogVisible.value = true;
};
const removeDia = (data: Tree) => {
  ElMessageBox.confirm("确定删除吗？", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    removeValidate(data.id).then((res) => {
      if (res.data) {
        remove(data.id).then((res) => {
          refreshTreeNode(data.parentId);
          ElMessage({
            type: "success",
            message: res.msg,
          });
        });
      } else {
        ElMessage({
          type: "error",
          message:
            "该节点及其全部子节点下有知识无法进行删除，请在知识管理中批量删除知识后再进行操作。",
        });
      }
    });
  });
};

const dialogVisible = ref(false);
const handleClose = () => {
  formRef.value.resetFields();
  dialogVisible.value = false;
};
const option = ref({
  column: [
    {
      label: "名称",
      prop: "name",
      span: 24,
      rules: [
        {
          required: true,
          message: "请输入名称",
          trigger: "blur",
        },
        {
          pattern: /^[\u4e00-\u9fa5_a-zA-Z0-9]{1,63}$/,
          message:
            "名称只能由大小写字母、数字、中文、下划线组成，长度为1-63位!",
          trigger: "blur",
        },
      ],
    },
  ],
});
interface objtype {
  id?: string;
  sort: number;
  currentId: string;
  name: string;
}
/** 节点操作（新增同级、子级，重命名） */
const handleSubmit = (form, done) => {
  console.log(form);
  let obj: Partial<objtype> = {
    sort: clickNodeData.value.sort,
  };
  if (diaTitle.value == "添加同级") {
    obj.currentId = clickNodeData.value.id;
    obj.name = form.name;
    addSub(obj)
      .then((res) => {
        // treeRef.value.insertAfter();
        refreshTreeNode(clickNodeData.value.parentId);
        done();
        handleClose();
        ElMessage({
          type: "success",
          message: res.msg,
        });
      })
      .catch(() => {
        done();
      });
  } else if (diaTitle.value == "添加子级") {
    obj.currentId = clickNodeData.value.id;
    obj.name = form.name;
    addSon(obj)
      .then((res) => {
        refreshTreeNode(clickNodeData.value.id);
        done();
        handleClose();
        ElMessage({
          type: "success",
          message: res.msg,
        });
      })
      .catch(() => {
        done();
      });
  } else if (diaTitle.value == "重命名") {
    obj.id = clickNodeData.value.id;
    obj.name = form.name;
    rename(obj)
      .then((res) => {
        refreshTreeNode(clickNodeData.value.parentId, clickNodeData.value);
        done();
        handleClose();
        ElMessage({
          type: "success",
          message: res.msg,
        });
      })
      .catch(() => {
        done();
      });
  }
};

let node_had = ref(null);
let resolve_had = ref(null);
/** 加载树 */
const loadNode = (node: Node, resolve: (data: Tree[]) => void) => {
  // console.log(node, "node");
  let params = {
    id: node.level === 0 ? "" : node.data.id,
  };
  if (node.level === 0) {
    // 修改顶级节点名称的时候用于重载树
    node_had.value = node; //这里是关键！在data里面定义一个变量，将node.level == 0的node存起来
    resolve_had.value = resolve; //同上，把node.level == 0的resolve也存起来
  }

  getTree(params).then((res) => {
    if (res.code == 200) {
      resolve(res.data.itemList);
    }
  });
};
/**
 * 单独刷新节点
 * guid: 当前节点的父级唯一标识节点
 */
const refreshTreeNode = (guid, crenode) => {
  let node = (treeRef.value as any).getNode(guid);
  // console.log(node, guid, crenode);
  if (node) {
    node.loaded = false;
    node.expand(); // 主动调用展开节点方法，重新查询该节点下的所有子节点
  } else {
    node_had.value.childNodes = []; //把存起来的node的子节点清空，不然会界面会出现重复树！
    loadNode(node_had.value, resolve_had.value);
  }
};

/** 导出 */
const exportData = () => {
  download().then((res) => {
    console.log(res);

    let blob = new Blob([res.data]);
    let url = window.URL.createObjectURL(blob); // 创建 url 并指向 blob
    let a = document.createElement("a");
    a.href = url;
    a.setAttribute(
      "download",
      decodeURI(res["headers"]["content-disposition"].split("filename=")[1])
    ); //文件名，注意看是要啥格式的
    a.click();
    window.URL.revokeObjectURL(url); // 释放该 url
  });
};
</script>

<style scoped lang="scss">
.card-header {
  display: flex;
  justify-content: space-between;

  .title {
    font-size: 18px;
    font-weight: bold;
    color: rgb(43 29 255 / 100%);
  }
}

.custom-tree-node {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: space-between;
  padding-right: 30px;

  .label-name {
    display: inline-block;
    max-width: calc(100vw - 660px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .btn-div {
    .el-link {
      margin-left: 20px;
    }
  }
}
</style>
